﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace MezmurStore2.Utility
{
    // Helper class for diagnostic output from the Azure web role.

    public class WebDiagnostics
    {
        // Trace sources - Think of these as multiple output channels. So write to the ConfigTrace when you're 
        // logging information about configuration, write to the WebTrace when you're logging information about
        // the web role activities themselves (e.g. page load, etc.).  You can add more sources if you want - they
        // give you more ability to control what is and isn't logged.  For instance, rather than a single WebTrace,
        // you might have a source per major component of your web app - Home page, administration, profile management,
        // etc.  Have a switch per Source so you can adjust the verbosity of logging per component.
        public TraceSource ConfigTrace;
        public TraceSource WebTrace;
        // Add additional sources here

        // Corresponding trace switches to control level of output for each source
        public SourceSwitch ConfigTraceSwitch { get; set; }
        public SourceSwitch WebTraceSwitch { get; set; }
        // Add additional switches 1:1 with trace sources here; hook them up in the ctor

        // Given a string representation of a tracing level, e.g. from the config file,
        // translate it to the SourceLevels enum needed.
        public SourceLevels SourceLevelFromString(string str)
        {
            SourceLevels lvl;

            try
            {
                lvl = (SourceLevels)Enum.Parse(typeof(SourceLevels), str, true);
            }
            catch (System.ArgumentException exp)
            {
                // Invalid value - just default to off.
                lvl = SourceLevels.Off;
            }

            return lvl;
        }

        // Event types
        public enum TraceEventID
        {
            traceGeneral = 0,           // General type
            traceFunctionEntry = 1,
            traceFunctionExit = 2,      // Note that can see just entry / exit by querying eventId lt 3
            traceException = 100,
            traceUnexpected = 200,
            traceFlow = 300             // Can see entry / exit plus errors with eventId le 200
        };

        public WebDiagnostics()
        {
            ConfigTraceSwitch = new SourceSwitch("ConfigTrace", "Controls level of output having to do with configuration information");
            WebTraceSwitch = new SourceSwitch("WebTrace", "Controls level of output having to do with web role information");
            ConfigTrace = new TraceSource("ConfigTrace");
            ConfigTrace.Switch = ConfigTraceSwitch;
            WebTrace = new TraceSource("WebTrace");
            WebTrace.Switch = WebTraceSwitch;
            GetTraceSwitchValuesFromRoleConfiguration();
        }

        public void GetTraceSwitchValuesFromRoleConfiguration()
        {
            ConfigTraceSwitch.Level = SourceLevelFromString(RoleEnvironment.GetConfigurationSettingValue("ConfigTrace"));
            WebTraceSwitch.Level = SourceLevelFromString(RoleEnvironment.GetConfigurationSettingValue("WebTrace"));
            // Uses Trace.WriteLine so that the information goes through regardless of the switch values
            Trace.WriteLine("GetTraceSwitchValuesFromRoleConfiguration - Trace switch values set:  Config=" + ConfigTraceSwitch.Level.ToString() +
                "  web=" + WebTraceSwitch.Level.ToString());
        }


        public void WriteDiagnosticInfo(TraceSource src, TraceEventType evtType, TraceEventID evtID, string msg)
        {
            if (src != null)
                src.TraceEvent(evtType, (int)evtID, msg);
        }

        public void WriteDiagnosticInfo(TraceSource src, TraceEventType evtType, TraceEventID evtID, string format, params object[] args)
        {
            if (src != null)
                src.TraceEvent(evtType, (int)evtID, format, args);
        }

        // Shortcut method for logging to the WebTrace source
        public void WriteWebDiagnosticInfo(TraceEventType evtType, TraceEventID evtID, string msg)
        {
            WriteDiagnosticInfo(WebTrace, evtType, evtID, msg);
        }
    }
}
